#include "tlv_buffer.h"
#include <cstring>

TLVBuffer::TLVBuffer(size_t capacity)
    : buffer_(capacity), writePos_(0) {}

TLVBuffer::~TLVBuffer() {}

bool TLVBuffer::writeRaw(TLVType type, const void* data, uint16_t length) {
    if (writePos_ + 4 + length > buffer_.size()) return false;

    uint16_t typeVal = static_cast<uint16_t>(type);
    std::memcpy(&buffer_[writePos_], &typeVal, 2);
    writePos_ += 2;

    std::memcpy(&buffer_[writePos_], &length, 2);
    writePos_ += 2;

    std::memcpy(&buffer_[writePos_], data, length);
    writePos_ += length;

    return true;
}

bool TLVBuffer::readTLV(size_t offset, TLV& out) const{
    if (offset + 4 > buffer_.size()) return false;

    uint16_t typeVal, length;
    std::memcpy(&typeVal, &buffer_[offset], 2);
    offset += 2;

    std::memcpy(&length, &buffer_[offset], 2);
    offset += 2;

    if (offset + length > buffer_.size()) return false;

    out.type = static_cast<TLVType>(typeVal);
    out.length = length;
    out.value.assign(buffer_.begin() + offset, buffer_.begin() + offset + length);

    return true;
}

const uint8_t* TLVBuffer::data() const { return buffer_.data(); }
size_t TLVBuffer::size() const { return writePos_; }
